package com.android.support.lib.universal.load;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.android.support.lib.universal.general.GeneralCache;
import com.android.support.lib.universal.util.Utilfile;
import com.android.support.lib.universal.util.Utilnum;
import com.lidroid.xutils.HttpUtils;
import com.lidroid.xutils.exception.HttpException;
import com.lidroid.xutils.http.HttpHandler;
import com.lidroid.xutils.http.ResponseInfo;
import com.lidroid.xutils.http.callback.RequestCallBack;

/**
 * 下载工具类 使用案例：
 * 
 * protected void listenner() { //是否需要重新下载 Boolean reBool=true; // 更新 Load
 * reLoad = LoadUtil.loadMap.get(id); if (reLoad != null) { // 防止线程错乱
 * if(reLoad.reLoad()){//判断是否需要重新下载 reBool=true; }else{ reBool=false; }
 * 
 * } if(reBool){//重新下载，支持断点续传下载 reLoad=LoadUtil.loadFile(context, id, url,
 * fileName, null, null, null, txtProgress, null, null, LoadState.IMG, uiHander,
 * loadProgressBar); }else{ //线程已经再下载，所以不需再重复下载，只需更新控件即可。 reLoad.setTxt(null,
 * null, null, txtProgress, null, null, LoadState.IMG, uiHander,
 * loadProgressBar); }
 * 
 * }
 * 
 * @author 彭治铭
 *
 */
public class LoadUtil {
	// 3000表示与服务器链接超时
	HttpUtils httpUtils = new HttpUtils(4000);
	// String为 Load的ID
	public Map<String, Load> loadMap = new HashMap<String, Load>();
	Utilnum utilnum = new Utilnum();

	/**
	 * 文件下载(需要有服务器的支持) 注意。首次调用时，建议使用以下方式调用(防止线程错乱,不能做到确保百分比) Load reload =
	 * LoadUtil.loadMap.get(id); if (reload != null) { // 非首次调用,防止线程错乱
	 * if(!reload.reLoad()){ //不需要重新下载，不做任何处理 return null; } }
	 * 
	 * 
	 * @param context
	 *            （可为null,为空时不会有错误通知） 上下文
	 * @param id
	 *            唯一标示(虽然是字符串类型，但是必须是纯数字，以便转化为int类型)
	 * @param url
	 *            下载URL,下载路径，不允许出现中文，不让无法下载。
	 * @param fileName
	 *            文件名（包含后缀），可以为空（null）,为空时会通过url获取文件名。
	 * @param txtState
	 *            状态文本框（可为null）
	 * @param txtCurrent
	 *            当前下载大小,文本框（可为null）
	 * @param txtTotal
	 *            总大小,文本框（可为null）
	 * @param txtProgress
	 *            进度,文本框（可为null）
	 * @param txtSpeed
	 *            下载速度,文本框（可为null）
	 * @param btnLoad
	 *            按钮
	 * @param model
	 *            按钮模式，以State类参数为准
	 * @param uiHander
	 *            用于更新UI界面
	 * @param progressBar
	 *            进度条
	 * @return
	 */
	public Load loadFile(final Context context, String id, final String url,
			String fileName, final TextView txtState,
			final TextView txtCurrent, final TextView txtTotal,
			final TextView txtProgress, final TextView txtSpeed,
			final Button btnLoad, int model, Handler uiHander,
			final ProgressBar progressBar) {
		// 完整路径（包含文件的后缀名）
		final String path;
		if (fileName == null || fileName.equals("")) {
			Utilfile utilfile = new Utilfile();
			fileName = utilfile.getFileName(url);
			utilfile = null;
		}
		path = GeneralCache.getLoadPath() + "/" + fileName;

		final Load load;
		if (loadMap.get(url) == null) {
			load = new Load(context, id, url, path, fileName);
		} else {
			load = loadMap.get(url);
		}
		/**
		 * 更新控件
		 */
		load.setTxt(txtState, txtCurrent, txtTotal, txtProgress, txtSpeed,
				btnLoad, model, uiHander, progressBar);
		load.setState(LoadState.LINEUP);
		// 参数一 下载url
		// 参数二 下载路径（完整名，报名文件名），如果文件夹不存在，会自行创建
		// 参数三 true如果目标文件存在，接着未完成的部分继续下载(断点续传)。服务器不支持RANGE时将从新下载。
		// 参数四 true如果从请求返回信息中获取到文件名，下载完成后自动重命名。 最好为false，不然无法检测文件是否已下载完成，而重复下载
		HttpHandler handler = httpUtils.download(url, path, true, false,
				new RequestCallBack<File>() {
					@Override
					public void onStart() {
						// TODO Auto-generated method stub
						super.onStart();
						// 在onstart方法里，不要执行任何函数，防止下载线程阻塞。
					}

					/**
					 * 每秒钟执行一次，因此可以计算当前的下载速度
					 */
					@Override
					public void onLoading(long total, long current,
							boolean isUploading) {
						// TODO Auto-generated method stub
						super.onLoading(total, current, isUploading);
						// 下载速度
						if (load.state == LoadState.DOWNLOAD) {
							load.setSpeed(utilnum.calculateSize(current
									- load.getS())
									+ "/S");
						}
						load.setS(current);
						// 状态
						load.setState(LoadState.DOWNLOAD);

						load.setByteCurrent(current);
						load.setByteTotal(total);
						load.setCurrent(utilnum.calculateSize(current));
						load.setTatal(utilnum.calculateSize(total));
						load.setProgress(utilnum.getPercent(current, total));
						if (load.getTxtCurrent() != null) {
							// 当前下载大小
							load.getTxtCurrent().setText(load.getCurrent());
						}
						if (load.getTxtTotal() != null) {
							// 总大小
							load.getTxtTotal().setText(load.getTatal());
						}
						if (load.getTxtSpeed() != null) {
							// 下载速度
							load.getTxtSpeed().setText(load.getSpeed());

						}
						if (load.getTxtProgress() != null) {
							// 下载进度
							load.getTxtProgress().setText(load.getProgress());
						}
						if (load.getProgressBar() != null) {
							// 进度条
							load.getProgressBar().setMax((int) total);
							load.getProgressBar().setProgress((int) current);
						}
					}

					@Override
					public void onSuccess(ResponseInfo<File> arg0) {
						// TODO Auto-generated method stub
						load.setState(LoadState.COMPLETE);
						Log.e("下载成功", "下载成功" + arg0);
					}

					@Override
					public void onFailure(HttpException arg0, String arg1) {
						// TODO Auto-generated method stub
						load.setState(LoadState.FAILURE);
						if ("maybe the file has downloaded completely"
								.equals(arg0.getMessage().trim())) {
							if (context != null) {
								Toast.makeText(context, "文件已下载", Toast.LENGTH_LONG).show();
							}
							Log.e("文件已下载", "文件已下载");
							load.setState(LoadState.COMPLETE);
						} else if ("java.net.SocketTimeoutException"
								.equals(arg0.getMessage().trim())
								|| arg0.getMessage()
										.contains(
												"org.apache.http.conn.ConnectTimeoutException")
								|| arg0.getMessage()
										.contains(
												"org.apache.http.conn.ConnectionPoolTimeoutException")) {
							if (context != null) {
								Toast.makeText(context, "服务器链接错误", Toast.LENGTH_LONG).show();
							}
							Log.e("服务器链接错误", "服务器链接错误");
						} else if (arg0
								.getMessage()
								.contains(
										"org.apache.http.conn.HttpHostConnectException")
								|| arg0.getMessage().contains(
										"java.net.UnknownHostException")) {
							if (context != null) {
								Toast.makeText(context, "请检测网络链接", Toast.LENGTH_LONG).show();
							}
							Log.e("请检测网络链接", "请检测网络链接");
						} else {
							Log.e("下载失败", "原因" + arg0.getMessage());
						}
					}
				});
		load.setHandler(handler);
		loadMap.put(load.getId(), load);
		return loadMap.get(load.getId());
	}
}
